home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- * ISO MPEG Audio Subgroup Software Simulation Group (1996)
- * ISO 13818-3 MPEG-2 Audio Encoder - Lower Sampling Frequency Extension
- *
- * $Id: common.c,v 1.2 1997/01/19 22:28:29 rowlands Exp $
- *
- * $Log: common.c,v $
- * Revision 1.2 1997/01/19 22:28:29 rowlands
- * Layer 3 bug fixes from Seymour Shlien
- *
- * Revision 1.1 1996/02/14 04:04:23 rowlands
- * Initial revision
- *
- * Received from Mike Coleman
- **********************************************************************/
-
-
- /***********************************************************************
- *
- * Global Include Files
- *
- ***********************************************************************/
-
- #include "common.h"
- #include <string.h> /* 1995-07-11 shn */
- #include <ctype.h>
- #include <assert.h>
- #include <stdlib.h>
-
- /***********************************************************************
- *
- * Global Variable Definitions
- *
- ***********************************************************************/
-
- char *mode_names[4] = { "stereo", "j-stereo", "dual-ch", "single-ch" };
- char *layer_names[3] = { "I", "II", "III" };
- char *version_names[2] = { "MPEG-2 LSF", "MPEG-1" };
-
- /* 1: MPEG-1, 0: MPEG-2 LSF, 1995-07-11 shn */
- double s_freq[2][4] = {{22.05, 24, 16, 0}, {44.1, 48, 32, 0}};
-
- /* 1: MPEG-1, 0: MPEG-2 LSF, 1995-07-11 shn */
- int bitrate[2][3][15] = {
- {{0,32,48,56,64,80,96,112,128,144,160,176,192,224,256},
- {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160},
- {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160}},
- {{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
- {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
- {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}}
- };
-
- double FAR multiple[64] = {
- 2.00000000000000, 1.58740105196820, 1.25992104989487,
- 1.00000000000000, 0.79370052598410, 0.62996052494744, 0.50000000000000,
- 0.39685026299205, 0.31498026247372, 0.25000000000000, 0.19842513149602,
- 0.15749013123686, 0.12500000000000, 0.09921256574801, 0.07874506561843,
- 0.06250000000000, 0.04960628287401, 0.03937253280921, 0.03125000000000,
- 0.02480314143700, 0.01968626640461, 0.01562500000000, 0.01240157071850,
- 0.00984313320230, 0.00781250000000, 0.00620078535925, 0.00492156660115,
- 0.00390625000000, 0.00310039267963, 0.00246078330058, 0.00195312500000,
- 0.00155019633981, 0.00123039165029, 0.00097656250000, 0.00077509816991,
- 0.00061519582514, 0.00048828125000, 0.00038754908495, 0.00030759791257,
- 0.00024414062500, 0.00019377454248, 0.00015379895629, 0.00012207031250,
- 0.00009688727124, 0.00007689947814, 0.00006103515625, 0.00004844363562,
- 0.00003844973907, 0.00003051757813, 0.00002422181781, 0.00001922486954,
- 0.00001525878906, 0.00001211090890, 0.00000961243477, 0.00000762939453,
- 0.00000605545445, 0.00000480621738, 0.00000381469727, 0.00000302772723,
- 0.00000240310869, 0.00000190734863, 0.00000151386361, 0.00000120155435,
- 1E-20
- };
-
- enum byte_order NativeByteOrder = order_unknown;
-
- /***********************************************************************
- *
- * Global Function Definitions
- *
- ***********************************************************************/
-
-
- /***********************************************************************
- * compute bitsperframe and mean_bits for a layer III frame
- **********************************************************************/
- void getframebits(layer *info, int stereo, int *bitsPerFrame, int *mean_bits) {
- int whole_SpF;
- double bit_rate,samp;
- int samplesPerFrame,bitsPerSlot;
- int sideinfo_len;
- int mode_gr;
-
- samp = s_freq[info->version][info->sampling_frequency];
- bit_rate = bitrate[info->version][info->lay-1][info->bitrate_index];
- samplesPerFrame = info->version == 1 ? 1152 : 576;
- bitsPerSlot = 8;
- mode_gr = (info->version == 1) ? 2 : 1; /* mode_gr = 2 */
-
- /* determine the mean bitrate for main data */
- sideinfo_len = 32;
- if ( info->version == 1 )
- { /* MPEG 1 */
- if ( stereo == 1 )
- sideinfo_len += 136;
- else
- sideinfo_len += 256;
- }
- else
- { /* MPEG 2 */
- if ( stereo == 1 )
- sideinfo_len += 72;
- else
- sideinfo_len += 136;
- }
-
-
-
-
- whole_SpF = (samplesPerFrame /samp)*(bit_rate / (double)bitsPerSlot);
- *bitsPerFrame = 8 * whole_SpF + (info->padding * 8);
- *mean_bits = (*bitsPerFrame - sideinfo_len) / mode_gr;
- }
-
-
-
-
- /* jsbound is ignored for layer 3 */
-
- int js_bound(lay, m_ext)
- int lay, m_ext;
- {
- static int jsb_table[3][4] = { { 4, 8, 12, 16 }, { 4, 8, 12, 16},
- { 0, 4, 8, 16} }; /* lay+m_e -> jsbound */
-
- if(lay<1 || lay >3 || m_ext<0 || m_ext>3) {
- if (m_ext!=10) /* mark taylor 5/99 added mode=10 */
- {
- fprintf(stderr, "js_bound bad layer/modext (%d/%d)\n", lay, m_ext);
- exit(1);
- }
- }
- return(jsb_table[lay-1][m_ext]);
- }
-
-
- void hdr_to_frps(fr_ps) /* interpret data in hdr str to fields in fr_ps */
- frame_params *fr_ps;
- {
- layer *hdr = fr_ps->header; /* (or pass in as arg?) */
-
- fr_ps->actual_mode = hdr->mode;
- fr_ps->stereo = (hdr->mode == MPG_MD_MONO) ? 1 : 2;
- if (hdr->lay == 2){
- printf("Only Layer 3 supported\n");
- exit(-1);}
- else fr_ps->sblimit = SBLIMIT;
- if(hdr->mode == MPG_MD_JOINT_STEREO)
- fr_ps->jsbound = js_bound(hdr->lay, hdr->mode_ext);
- else
- fr_ps->jsbound = fr_ps->sblimit;
- /* alloc, tab_num set in pick_table */
- }
-
-
- void WriteHdr(fr_ps, s)
- frame_params *fr_ps;
- FILE *s;
- {
- layer *info = fr_ps->header;
-
- fprintf(s, "HDR: s=FFF, id=%X, l=%X, ep=%s, br=%X, sf=%X, pd=%X, ",
- info->version, info->lay, ((info->error_protection) ? "on" : "off"),
- info->bitrate_index, info->sampling_frequency, info->padding);
- fprintf(s, "pr=%X, m=%X, js=%X, c=%X, o=%X, e=%X\n",
- info->extension, info->mode, info->mode_ext,
- info->copyright, info->original, info->emphasis);
- fprintf(s, "alg.=%s, layer=%s, tot bitrate=%d, sfrq=%.1f\n",
- version_names[info->version], layer_names[info->lay-1],
- bitrate[info->version][info->lay-1][info->bitrate_index],
- s_freq[info->version][info->sampling_frequency]);
- fprintf(s, "mode=%s, sblim=%d, jsbd=%d, ch=%d\n",
- mode_names[info->mode], fr_ps->sblimit, fr_ps->jsbound, fr_ps->stereo);
- fflush(s);
- }
-
-
-
- int BitrateIndex(layr, bRate, version) /* convert bitrate in kbps to index */
- int layr; /* 1 or 2 */
- int bRate; /* legal rates from 32 to 448 */
- int version; /* MPEG-1 or MPEG-2 LSF */
- {
- int index = 0;
- int found = 0;
-
- while(!found && index<15) {
- if(bitrate[version][layr-1][index] == bRate)
- found = 1;
- else
- ++index;
- }
- if(found)
- return(index);
- else {
- fprintf(stderr, "BitrateIndex: %d (layer %d) is not a legal bitrate\n",
- bRate, layr);
- return(-1); /* Error! */
- }
- }
-
- int SmpFrqIndex(sRate, version) /* convert samp frq in Hz to index */
- long sRate; /* legal rates 16000, 22050, 24000, 32000, 44100, 48000 */
- int *version;
- {
- if (sRate == 44100L) {
- *version = MPEG_AUDIO_ID; return(0);
- }
- else if (sRate == 48000L) {
- *version = MPEG_AUDIO_ID; return(1);
- }
- else if (sRate == 32000L) {
- *version = MPEG_AUDIO_ID; return(2);
- }
- else if (sRate == 24000L) {
- *version = MPEG_PHASE2_LSF; return(1);
- }
- else if (sRate == 22050L) {
- *version = MPEG_PHASE2_LSF; return(0);
- }
- else if (sRate == 16000L) {
- *version = MPEG_PHASE2_LSF; return(2);
- }
- else {
- fprintf(stderr, "SmpFrqIndex: %ld is not a legal sample rate\n", sRate);
- return(-1); /* Error! */
- }
- }
-
- /*******************************************************************************
- *
- * Allocate number of bytes of memory equal to "block".
- *
- *******************************************************************************/
-
- void FAR *mem_alloc(block, item)
- unsigned long block;
- char *item;
- {
-
- void *ptr;
-
- ptr = (void FAR *) malloc(block<<1); /* allocate twice as much memory as needed. fixes dodgy
- memory problem on most systems */
-
- if (ptr != NULL){
- memset(ptr, 0, block);
- }
- else{
- printf("Unable to allocate %s\n", item);
- exit(0);
- }
- return(ptr);
- }
-
-
- /****************************************************************************
- *
- * Free memory pointed to by "*ptr_addr".
- *
- *****************************************************************************/
-
- void mem_free(ptr_addr)
- void **ptr_addr;
- {
-
- if (*ptr_addr != NULL){
- free(*ptr_addr);
- *ptr_addr = NULL;
- }
-
- }
-
-
- /*****************************************************************************
- *
- * Routines to determine byte order and swap bytes
- *
- *****************************************************************************/
-
- enum byte_order DetermineByteOrder()
- {
- char s[ sizeof(long) + 1 ];
- union
- {
- long longval;
- char charval[ sizeof(long) ];
- } probe;
- probe.longval = 0x41424344L; /* ABCD in ASCII */
- strncpy( s, probe.charval, sizeof(long) );
- s[ sizeof(long) ] = '\0';
- /* fprintf( stderr, "byte order is %s\n", s ); */
- if ( strcmp(s, "ABCD") == 0 )
- return order_bigEndian;
- else
- if ( strcmp(s, "DCBA") == 0 )
- return order_littleEndian;
- else
- return order_unknown;
- }
-
- void SwapBytesInWords( short *loc, int words )
- {
- int i;
- short thisval;
- char *dst, *src;
- src = (char *) &thisval;
- for ( i = 0; i < words; i++ )
- {
- thisval = *loc;
- dst = (char *) loc++;
- dst[0] = src[1];
- dst[1] = src[0];
- }
- }
-
- /*****************************************************************************
- *
- * Read Audio Interchange File Format (AIFF) headers.
- *
- *****************************************************************************/
-
- int aiff_read_headers( FILE *file_ptr, IFF_AIFF *aiff_ptr )
- {
- int chunkSize, subSize, sound_position;
-
- if ( fseek(file_ptr, 0, SEEK_SET) != 0 )
- return -1;
-
- if ( Read32BitsHighLow(file_ptr) != IFF_ID_FORM )
- return -1;
-
- chunkSize = Read32BitsHighLow( file_ptr );
-
- if ( Read32BitsHighLow(file_ptr) != IFF_ID_AIFF )
- return -1;
-
- sound_position = 0;
- while ( chunkSize > 0 )
- {
- chunkSize -= 4;
- switch ( Read32BitsHighLow(file_ptr) )
- {
-
- case IFF_ID_COMM:
- chunkSize -= subSize = Read32BitsHighLow( file_ptr );
- aiff_ptr->numChannels = Read16BitsHighLow( file_ptr );
- subSize -= 2;
- aiff_ptr->numSampleFrames = Read32BitsHighLow( file_ptr );
- subSize -= 4;
- aiff_ptr->sampleSize = Read16BitsHighLow( file_ptr );
- subSize -= 2;
- aiff_ptr->sampleRate = ReadIeeeExtendedHighLow( file_ptr );
- subSize -= 10;
- while ( subSize > 0 )
- {
- getc( file_ptr );
- subSize -= 1;
- }
- break;
-
- case IFF_ID_SSND:
- chunkSize -= subSize = Read32BitsHighLow( file_ptr );
- aiff_ptr->blkAlgn.offset = Read32BitsHighLow( file_ptr );
- subSize -= 4;
- aiff_ptr->blkAlgn.blockSize = Read32BitsHighLow( file_ptr );
- subSize -= 4;
- sound_position = ftell( file_ptr ) + aiff_ptr->blkAlgn.offset;
- if ( fseek(file_ptr, (long) subSize, SEEK_CUR) != 0 )
- return -1;
- aiff_ptr->sampleType = IFF_ID_SSND;
- break;
-
- default:
- chunkSize -= subSize = Read32BitsHighLow( file_ptr );
- while ( subSize > 0 )
- {
- getc( file_ptr );
- subSize -= 1;
- }
- break;
- }
- }
- return sound_position;
- }
-
- /*****************************************************************************
- *
- * Seek past some Audio Interchange File Format (AIFF) headers to sound data.
- *
- *****************************************************************************/
-
- int aiff_seek_to_sound_data( FILE *file_ptr )
- {
- if ( fseek(file_ptr, AIFF_FORM_HEADER_SIZE + AIFF_SSND_HEADER_SIZE, SEEK_SET) != 0 )
- return(-1);
- return(0);
- }
-
- /*******************************************************************************
- *
- * Write Audio Interchange File Format (AIFF) headers.
- *
- *******************************************************************************/
-
- int aiff_write_headers( FILE *file_ptr, IFF_AIFF *aiff_ptr )
- {
- int chunkSize;
- int sampleBytes = (aiff_ptr->sampleSize / 8) + (aiff_ptr->sampleSize % 8 ? 1 : 0);
-
- if ( fseek(file_ptr, 0L, SEEK_SET) != 0 )
- return -1;
-
- /* write FORM chunk */
- chunkSize = 8 + 18 + 8 + aiff_ptr->numChannels * aiff_ptr->numSampleFrames * sampleBytes;
- Write32BitsHighLow( file_ptr, IFF_ID_FORM );
- Write32BitsHighLow( file_ptr, chunkSize );
- Write32BitsHighLow( file_ptr, IFF_ID_AIFF );
- /* write COMM chunk */
- Write32BitsHighLow( file_ptr, IFF_ID_COMM );
- Write32BitsHighLow( file_ptr, 18 ); /* chunk size */
- Write16BitsHighLow( file_ptr, aiff_ptr->numChannels );
- Write32BitsHighLow( file_ptr, aiff_ptr->numSampleFrames );
- Write16BitsHighLow( file_ptr, aiff_ptr->sampleSize );
- WriteIeeeExtendedHighLow( file_ptr, aiff_ptr->sampleRate );
- /* write SSND chunk header */
- chunkSize = 8 + aiff_ptr->numChannels * aiff_ptr->numSampleFrames * sampleBytes;
- Write32BitsHighLow( file_ptr, IFF_ID_SSND );
- Write32BitsHighLow( file_ptr, chunkSize );
- Write32BitsHighLow( file_ptr, 0 ); /* offset */
- Write32BitsHighLow( file_ptr, 0 ); /* block size */
- return 0;
- }
-
- /*****************************************************************************
- *
- * bit_stream.c package
- * Author: Jean-Georges Fritsch, C-Cube Microsystems
- *
- *****************************************************************************/
-
- /********************************************************************
- This package provides functions to write (exclusive or read)
- information from (exclusive or to) the bit stream.
-
- If the bit stream is opened in read mode only the get functions are
- available. If the bit stream is opened in write mode only the put
- functions are available.
- ********************************************************************/
-
- /*open_bit_stream_w(); open the device to write the bit stream into it */
- /*open_bit_stream_r(); open the device to read the bit stream from it */
- /*close_bit_stream(); close the device containing the bit stream */
- /*alloc_buffer(); open and initialize the buffer; */
- /*desalloc_buffer(); empty and close the buffer */
- /*back_track_buffer(); goes back N bits in the buffer */
- /*unsigned int get1bit(); read 1 bit from the bit stream */
- /*unsigned long look_ahead(); grep the next N bits in the bit stream without*/
- /* changing the buffer pointer */
- /*put1bit(); write 1 bit from the bit stream */
- /*put1bit(); write 1 bit from the bit stream */
- /*putbits(); write N bits from the bit stream */
- /*unsigned long sstell(); return the current bit stream length (in bits) */
- /*int end_bs(); return 1 if the end of bit stream reached otherwise 0 */
- /*int seek_sync(); return 1 if a sync word was found in the bit stream */
- /* otherwise returns 0 */
-
- /* refill the buffer from the input device when the buffer becomes empty */
- int refill_buffer(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- register int i=bs->buf_size-2-bs->buf_byte_idx;
- register unsigned long n=1;
- register int index=0;
- char val[2];
-
- #ifndef _BLADEDLL
- while ((i>=0) && (!bs->eob)) {
-
- if (bs->format == BINARY)
- n = fread(&bs->buf[i--], sizeof(unsigned char), 1, bs->pt);
-
- else {
- while((index < 2) && n) {
- n = fread(&val[index], sizeof(char), 1, bs->pt);
- switch (val[index]) {
- case 0x30:
- case 0x31:
- case 0x32:
- case 0x33:
- case 0x34:
- case 0x35:
- case 0x36:
- case 0x37:
- case 0x38:
- case 0x39:
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x44:
- case 0x45:
- case 0x46:
- index++;
- break;
- default: break;
- }
- }
-
- if (val[0] <= 0x39) bs->buf[i] = (val[0] - 0x30) << 4;
- else bs->buf[i] = (val[0] - 0x37) << 4;
- if (val[1] <= 0x39) bs->buf[i--] |= (val[1] - 0x30);
- else bs->buf[i--] |= (val[1] - 0x37);
- index = 0;
- }
-
- if (!n) {
- bs->eob= i+1;
- }
-
- }
- #endif
- return 0;
- }
-
-
- /* empty the buffer to the output device when the buffer becomes full */
- /* mt 3/99: modified so we can call empty_buffer even if buffer is not full */
- void empty_buffer(bs, minimum)
- Bit_stream_struc *bs; /* bit stream structure */
- int minimum; /* end of the buffer to empty */
- {
- register int i;
-
- #ifndef DISTRIB
- #if BS_FORMAT == BINARY
- for (i=bs->buf_size-1;i>=minimum;i--)
- {
- #ifdef _BLADEDLL
- if (bs->nOutBufPos<BUFFER_SIZE)
- {
- bs->pbtOutBuf[bs->nOutBufPos++]=bs->buf[i];
- }
- else
- {
- assert(0);
- }
- #else
- fwrite(&bs->buf[i], sizeof(unsigned char), 1, bs->pt);
- #endif // _BLADEDLL
- }
- #else
- static char *he = "0123456789ABCDEF";
-
- for (i=bs->buf_size-1;i>=minimum;i--) {
- char val[2];
- val[0] = he[((bs->buf[i] >> 4) & 0x0F)];
- val[1] = he[(bs->buf[i] & 0x0F)];
- fwrite(val, sizeof(char), 2, bs->pt);
- }
- #endif // BS_FORMAT==BINARY
-
- #ifndef _BLADEDLL
- // NEW SS to assist in debugging
- // Only file for files, not for the output buffer
- fflush(bs->pt);
- #endif
- #endif
-
- /* for (i=minimum-1; i>=0; i--) */
- for (i=minimum-1; i>=bs->buf_byte_idx+1; i--)
- bs->buf[bs->buf_size - minimum + i] = bs->buf[i];
-
- /* bs->buf_byte_idx = bs->buf_size -1 - minimum; */
- bs->buf_byte_idx = bs->buf_size -1 - minimum + bs->buf_byte_idx + 1;
- bs->buf_bit_idx = 8;
- }
-
- /* open the device to write the bit stream into it */
- void open_bit_stream_w(bs, bs_filenam, size)
- Bit_stream_struc *bs; /* bit stream structure */
- char *bs_filenam; /* name of the bit stream file */
- int size; /* size of the buffer */
- {
- #ifdef _BLADEDLL
- // Initialize output buffer
- bs->pbtOutBuf=NULL;
- bs->nOutBufPos=0;
- #else
- if (!strcmp(bs_filenam, "-")) {
- /* Write to standard output. */
- bs->pt = stdout;
- } else {
- if ((bs->pt = fopen(bs_filenam, "wb")) == NULL) {
- printf("Could not create \"%s\".\n", bs_filenam);
- exit(1);
- }
- }
- #endif
- alloc_buffer(bs, size);
- bs->buf_byte_idx = size-1;
- bs->buf_bit_idx=8;
- bs->totbit=0;
- bs->mode = WRITE_MODE;
- bs->eob = FALSE;
- bs->eobs = FALSE;
- }
-
-
- /*close the device containing the bit stream after a write process*/
- void close_bit_stream_w(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- // Flush last bytes
- empty_buffer(bs, bs->buf_byte_idx);
-
- #ifndef _BLADEDLL
- // Close the file
- fclose(bs->pt);
- #endif // _BLADEDLL
-
- // Deallocate all buffers
- desalloc_buffer(bs);
- }
-
- /*open and initialize the buffer; */
- void alloc_buffer(bs, size)
- Bit_stream_struc *bs; /* bit stream structure */
- int size;
- {
- bs->buf = (unsigned char FAR *) mem_alloc(size*sizeof(unsigned
- char), "buffer");
- bs->buf_size = size;
- }
-
- /*empty and close the buffer */
- void desalloc_buffer(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- free(bs->buf);
- }
-
- int putmask[9]={0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff};
- int clearmask[9]={0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x0};
- int mask[8]={0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
-
- #if 0
- /*read 1 bit from the bit stream */
- unsigned int get1bit(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- unsigned int bit;
- register int i;
-
- bs->totbit++;
-
- if (!bs->buf_bit_idx) {
- bs->buf_bit_idx = 8;
- bs->buf_byte_idx--;
- if ((bs->buf_byte_idx < MINIMUM) || (bs->buf_byte_idx < bs->eob)) {
- if (bs->eob)
- bs->eobs = TRUE;
- else {
- for (i=bs->buf_byte_idx; i>=0;i--)
- bs->buf[bs->buf_size-1-bs->buf_byte_idx+i] = bs->buf[i];
- refill_buffer(bs);
- bs->buf_byte_idx = bs->buf_size-1;
- }
- }
- }
- bit = bs->buf[bs->buf_byte_idx]&mask[bs->buf_bit_idx-1];
- bit = bit >> (bs->buf_bit_idx-1);
- bs->buf_bit_idx--;
- return(bit);
- }
- #endif
-
- /*write 1 bit from the bit stream */
- void put1bit(bs, bit)
- Bit_stream_struc *bs; /* bit stream structure */
- int bit; /* bit to write into the buffer */
- {
- bs->totbit++;
-
- bs->buf[bs->buf_byte_idx] |= (bit&0x1) << (bs->buf_bit_idx-1);
- bs->buf_bit_idx--;
- if (!bs->buf_bit_idx) {
- bs->buf_bit_idx = 8;
- bs->buf_byte_idx--;
- if (bs->buf_byte_idx < 0)
- empty_buffer(bs, MINIMUM);
- bs->buf[bs->buf_byte_idx] = 0;
- }
- }
-
- /*look ahead for the next N bits from the bit stream */
- unsigned long look_ahead(bs, N)
- Bit_stream_struc *bs; /* bit stream structure */
- int N; /* number of bits to read from the bit stream */
- {
- unsigned long val=0;
- register int j = N;
- register int k, tmp;
- register int bit_idx = bs->buf_bit_idx;
- register int byte_idx = bs->buf_byte_idx;
-
- if (N > MAX_LENGTH)
- printf("Cannot read or write more than %d bits at a time.\n", MAX_LENGTH);
-
- while (j > 0) {
- if (!bit_idx) {
- bit_idx = 8;
- byte_idx--;
- }
- k = Min (j, bit_idx);
- tmp = bs->buf[byte_idx]&putmask[bit_idx];
- tmp = tmp >> (bit_idx-k);
- val |= tmp << (j-k);
- bit_idx -= k;
- j -= k;
- }
- return(val);
- }
-
- /*write N bits into the bit stream */
- void putbits(bs, val, N)
- Bit_stream_struc *bs; /* bit stream structure */
- unsigned int val; /* val to write into the buffer */
- int N; /* number of bits of val */
- {
- register int j = N;
- register int k, tmp;
-
- if (N > MAX_LENGTH)
- printf("Cannot read or write more than %d bits at a time.\n", MAX_LENGTH);
-
- bs->totbit += N;
- while (j > 0) {
- k = Min(j, bs->buf_bit_idx);
- tmp = val >> (j-k);
- bs->buf[bs->buf_byte_idx] |= (tmp&putmask[k]) << (bs->buf_bit_idx-k);
- bs->buf_bit_idx -= k;
- if (!bs->buf_bit_idx) {
- bs->buf_bit_idx = 8;
- bs->buf_byte_idx--;
- if (bs->buf_byte_idx < 0)
- empty_buffer(bs, MINIMUM);
- bs->buf[bs->buf_byte_idx] = 0;
- }
- j -= k;
- }
- }
-
-
- /*return the current bit stream length (in bits)*/
- unsigned long sstell(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- return(bs->totbit);
- }
-
- /*return the status of the bit stream*/
- /* returns 1 if end of bit stream was reached */
- /* returns 0 if end of bit stream was not reached */
- int end_bs(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- return(bs->eobs);
- }
-
- /*****************************************************************************
- *
- * End of bit_stream.c package
- *
- *****************************************************************************/
-
-